		TITLE	RELOC_INSTALL - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SEGMENTS
;		INCLUDE	FIX2TEMP
		INCLUDE	RELOCSS

		PUBLIC	RELOC_INSTALL,LIBASE_RELOC_INSTALL,INIT_SET_RELOC_BITS


		.DATA

		EXTERNDEF	LIBASE_TEMP_RECORD:BYTE,BITS_TABLE:BYTE,FIX2_LD_TYPE:BYTE

		EXTERNDEF	RELOC_COUNT:DWORD,OPTI_RELOC_CLEAR:DWORD,LIDATA_RELOCS_START:DWORD,RELOC_BITS:DWORD
		EXTERNDEF	LIDATA_RELOCS_NEXT:DWORD,RELOC_HIGH_WATER:DWORD,FIX2_SM_START:DWORD,FIX2_EXEPACK_BASE:DWORD
		EXTERNDEF	FIX2_STACK_DELTA:DWORD,FIRST_RELOC_GINDEX:DWORD,LAST_RELOC_GINDEX:DWORD

		EXTERNDEF	RELOC_GARRAY:STD_PTR_S,RELOC_STUFF:ALLOCS_STRUCT


		.CODE	PASS2_TEXT

		EXTERNDEF	GET_NEW_LOG_BLK:PROC,MOVE_LDATA_1:PROC,COMMON_INST_INIT:PROC,RELOC_POOL_GET:PROC


RELOC_LIDATA	PROC
		;
		;
		;
		MOV	ESI,LIDATA_RELOCS_NEXT
		MOV	EDI,16

		ADD	EDI,ESI

		MOV	[ESI],EAX
		MOV	4[ESI],EBX

		MOV	8[ESI],ECX
		MOV	12[ESI],EDX

		POP	ESI
		MOV	LIDATA_RELOCS_NEXT,EDI

		RET

RELOC_LIDATA	ENDP


INIT_RELOC1	LABEL	PROC

		POP	ESI
		CALL	INIT_RELOC

RELOC_INSTALL	PROC
		;
		;EDI IS PHYS_PTR
		;EAX IS OFFSET IN ADDRESS SPACE .LW
		;EBX IS _RL_IMP_OFFSET, OFFSET FROM DX
		;CL IS FIXUPP TYPE
		;CH IS FIXUPP FLAGS	;0=INTERNAL REF,1=IMPORT-BY-NUMBER,2=IMPORT-BY-NAME,3=OS-TYPE,...., 4 MEANS ADDITIVE
		;			;8 MEANS IGNORE MOVABILITY, DON'T LOOK FOR ENTRY-POINT
		;EDX IS _RL_IMP_MODULE, OS2_NUMBER, OR PARAGRAPH
		;
		PUSH	ESI
		MOV	ESI,RELOC_STUFF.ALLO_HASH_TABLE_PTR

		TEST	ESI,ESI
		JZ	INIT_RELOC1
		;
		;LIDATA IS SPECIAL...
		;
		TEST	FIX2_LD_TYPE,MASK BIT_LI
		JNZ	RELOC_LIDATA
		;
		;SET APPROPRIATE # OF BITS PLEASE
		;
		CALL	SET_RELOC_BITS

		MOV	ESI,EBX
		MOV	EBX,FIX2_EXEPACK_BASE

		SUB	EAX,EBX			;OFFSET FROM PACKING BASE
		MOV	BL,CH
		;
		;IF ITS ADDITIVE, JUST ADD IT TO LIST, NO HASHING...
		;
		AND	BL,4
		JNZ	RELOC_ADDITIVE

		PUSH	EAX
		CALL	GET_RELOC_ENTRY 	;RETURNS ECX PTR
		;
		;HERE IT IS, LINK IN POINTER TO LAST REFERENCE PLEASE...
		;
		ASSUME	ECX:PTR RELOC_STRUCT

		MOV	EBX,[ECX]._RL_SEG_OFFSET
		POPM	EAX

		MOV	WPTR [EDI],BX
		MOV	[ECX]._RL_SEG_OFFSET,EAX

		POP	ESI

		RET

RELOC_ADDITIVE::
		;
		;NO HASH LINK OR RELOC-INLINE LINK
		;
		PUSH	ECX
		MOV	EDI,EAX

		MOV	EAX,SIZE RELOC_STRUCT
		CALL	RELOC_POOL_GET

		MOV	EBX,EAX
		INSTALL_POINTER_GINDEX	RELOC_GARRAY
		MOV	ECX,FIRST_RELOC_GINDEX

;		MOV	ECX,LAST_RELOC_GINDEX

;		TEST	ECX,ECX
;		JZ	RA_1

;		CONVERT	ECX,ECX,RELOC_GARRAY
;		ASSUME	ECX:PTR RELOC_STRUCT

;		MOV	[ECX]._RL_NEXT_RELOC_GINDEX,EAX

;RA_2:
;		MOV	LAST_RELOC_GINDEX,EAX

		MOV	FIRST_RELOC_GINDEX,EAX

		XOR	EAX,EAX
		MOV	[EBX]._RL_SEG_OFFSET,EDI

		MOV	[EBX]._RL_NEXT_HASH_GINDEX,EAX
		MOV	[EBX]._RL_NEXT_RELOC_GINDEX,ECX		;WAS EAX

		MOV	EAX,RELOC_COUNT
		POP	ECX

		MOV	[EBX]._RL_TARG_OFFSET,ESI
		MOV	[EBX]._RL_OS2_NUMBER,EDX

		INC	EAX
		MOV	[EBX]._RL_FLAGS,ECX

		MOV	RELOC_COUNT,EAX
		POP	ESI

		RET

;RA_1:
;		MOV	FIRST_RELOC_GINDEX,EAX
;		JMP	RA_2

RELOC_INSTALL	ENDP


LIBASE_RELOC_INSTALL	PROC
		;
		;SET APPROPRIATE # OF BITS PLEASE
		;
		CALL	SET_RELOC_BITS

		PUSH	ESI
		MOV	ESI,EBX

		MOV	EBX,FIX2_EXEPACK_BASE

		SUB	EAX,EBX
		MOV	BL,CH
		;
		;IF ITS ADDITIVE, JUST ADD IT TO LIST, NO HASHING...
		;
		AND	BL,4
		JNZ	RELOC_ADDITIVE

		PUSH	EAX
		CALL	GET_RELOC_ENTRY 	;RETURNS DS:BX

		ASSUME	ECX:PTR RELOC_STRUCT

		POP	ESI
		MOV	EAX,OFF LIBASE_TEMP_RECORD

		MOV	EBX,[ECX]._RL_SEG_OFFSET
		MOV	EDX,FIX2_EXEPACK_BASE

		MOV	[ECX]._RL_SEG_OFFSET,ESI
		ADD	EDX,ESI

		MOV	[EAX],EBX
		MOV	ECX,2

		POP	ESI
		JMP	MOVE_LDATA_1

LIBASE_RELOC_INSTALL	ENDP


INIT_RELOC	PROC	NEAR
		;
		;
		;
		PUSHAD

		MOV	EAX,OFF RELOC_STUFF
		CALL	COMMON_INST_INIT
		;
		;NEED BLOCK TO DO RELOC BITS
		;
		CALL	GET_NEW_LOG_BLK

		MOV	EDI,EAX
		MOV	RELOC_BITS,EAX
if	page_size EQ 16K
		ADD	EAX,8K

		MOV	LIDATA_RELOCS_NEXT,EAX
		MOV	LIDATA_RELOCS_START,EAX
endif
		MOV	ECX,OPTI_RELOC_CLEAR
		XOR	EAX,EAX

		REP	STOSD

if	page_size EQ 8K
		CALL	GET_NEW_LOG_BLK

		MOV	LIDATA_RELOCS_NEXT,EAX
		MOV	LIDATA_RELOCS_START,EAX
endif
		POPAD

		RET

INIT_RELOC	ENDP


GET_RELOC_ENTRY PROC	NEAR
		;
		;RETURNS ECX
		;
		;EDI MUST BE PRESERVED
		;
		;ESI=OFFSET
		;EDX=OS2_NUMBER, MODULE #, OR PARAGRAPH
		;ECX IS FLAGS
		;
		PUSHM	EBP,EDI

		PUSHM	EDX,ECX	;SAVE REGS WHILE CALC HASH

		ROL	CH,4
		MOV	EAX,ESI

		SHL	EDX,16
		XOR	CL,CH

		OR	EAX,EDX
		XOR	EDX,EDX

		MOV	EBX,RELOC_STUFF.ALLO_HASH_TABLE_PTR
		MOV	DL,CL

		HASHDIV	RELOC_STUFF.ALLO_HASH

		POPM	ECX,EBP			;EBP = MODULE, ECX = FLAGS

		MOV	EAX,DPTR [EBX+EDX*4]
		LEA	EBX,[EBX+EDX*4 - RELOC_STRUCT._RL_NEXT_HASH_GINDEX]

NAME_NEXT:
		TEST	EAX,EAX
		JZ	DO1

		CONVERT	EAX,EAX,RELOC_GARRAY
		ASSUME	EAX:PTR RELOC_STRUCT

		;
		;IS IT A MATCH?
		;
		MOV	EBX,EAX
		MOV	EDI,[EAX]._RL_TARG_OFFSET
		ASSUME	EBX:PTR RELOC_STRUCT

		MOV	EDX,[EAX]._RL_OS2_NUMBER
		MOV	EAX,[EAX]._RL_NEXT_HASH_GINDEX

		CMP	EDI,ESI
		JNZ	NAME_NEXT

		CMP	EBP,EDX
		JNZ	NAME_NEXT

		CMP	[EBX]._RL_FLAGS,ECX
		JNZ	NAME_NEXT

		MOV	ECX,EBX
		POPM	EDI,EBP

		RET

DO1:
		;
		;EBX GETS POINTER
		;
		PUSHM	ESI
		MOV	ESI,EBX

		MOV	EAX,SIZE RELOC_STRUCT
		CALL	RELOC_POOL_GET

		MOV	EBX,EAX
		ASSUME	EBX:PTR RELOC_STRUCT
		INSTALL_POINTER_GINDEX	RELOC_GARRAY
		MOV	[ESI].RELOC_STRUCT._RL_NEXT_HASH_GINDEX,EAX

		MOV	ESI,LAST_RELOC_GINDEX
		MOV	[EBX]._RL_OS2_NUMBER,EBP

		TEST	ESI,ESI
		JZ	FIRST_RELOC

		CONVERT	ESI,ESI,RELOC_GARRAY
		ASSUME	ESI:PTR RELOC_STRUCT

		MOV	[ESI]._RL_NEXT_RELOC_GINDEX,EAX
		XOR	ESI,ESI
FR_RET:

		MOV	[EBX]._RL_NEXT_RELOC_GINDEX,ESI
		MOV	LAST_RELOC_GINDEX,EAX

		XOR	EAX,EAX
		POP	ESI

		MOV	[EBX]._RL_NEXT_HASH_GINDEX,EAX
;		MOV	[EBX]._RL_NEXT_RELOC_GINDEX,EAX

		DEC	EAX
		MOV	[EBX]._RL_TARG_OFFSET,ESI

		MOV	[EBX]._RL_SEG_OFFSET,EAX
		MOV	EAX,RELOC_COUNT

		MOV	[EBX]._RL_FLAGS,ECX
		INC	EAX

		POPM	EDI,EBP

		MOV	ECX,EBX
		MOV	RELOC_COUNT,EAX

		RET

FIRST_RELOC:
		MOV	FIRST_RELOC_GINDEX,EAX
		JMP	FR_RET

GET_RELOC_ENTRY ENDP


SET_RELOC_BITS_RTN	PROC	NEAR
		;
		;EAX IS OFFSET FROM SEGMOD
		;
		;
		PUSHM	ESI,EAX

		MOV	ESI,EAX
		MOV	EAX,FIX2_STACK_DELTA

		PUSH	ECX
		ADD	ESI,EAX

		MOV	EAX,FIX2_SM_START
		PUSH	EBX

		SUB	ESI,EAX
		CMP	CH,7				;IF OS-TYPE FIXUPP, SET JUST ONE BIT

		MOV	AL,1
		JZ	L1$

		AND	ECX,0FFH			;ELSE DO IT BASED ON SIZE OF FIXUPP-TYPE
		MOV	EBX,OFF BITS_TABLE

		MOV	AL,BYTE PTR[EBX+ECX]
		;
		;SI IS BIT #
		;AL IS # OF BITS
		;
L1$:
		AND	EAX,0FH
		MOV	EBX,ESI

		ADD	ESI,EAX		;UPDATE BY # OF BITS FOR HIGH-WATER
		MOV	CL,BL

		SHR	EBX,3		;DIVIDE BY 8 FOR BYTE #
		AND	CL,7		;MOD 8 FOR BIT # IN THAT BYTE

		ADD	EBX,RELOC_BITS
		MOV	AH,1

		SHL	AH,CL		;THAT BIT...
		MOV	CH,BYTE PTR[EBX]
L2$:
		OR	CH,AH
L21$:
		DEC	AL
		JZ	L3$

		SHL	AH,1
		JNC	L2$

		MOV	BYTE PTR[EBX],CH
		MOV	AH,1

		MOV	CH,BYTE PTR[EBX+1]
		INC	EBX

		OR	CH,AH
		JMP	L21$

L3$:
		MOV	BYTE PTR[EBX],CH
		MOV	EAX,RELOC_HIGH_WATER

		POPM	EBX,ECX

		CMP	EAX,ESI
		JA	L9$
		MOV	RELOC_HIGH_WATER,ESI
L9$:
		POPM	EAX,ESI

		RET

SET_RELOC_BITS_RTN	ENDP


INIT_SET_RELOC_BITS	PROC

		MOV	EAX,OFF SET_RELOC_BITS_RTN

		BITT	CHECK_RELOCATIONS		;SKIP IF NOT CHECKING FOR OVERLAP
		JZ	L99$

		MOV	EAX,OFF RETT

L99$:
		MOV	SET_RELOC_BITS,EAX
RETT:
		RET

INIT_SET_RELOC_BITS	ENDP


		.DATA?

		ALIGN	4

SET_RELOC_BITS	DD	?


		END

